#include "DetectionCheckWorker.h"

namespace coolpool
{

	DetectionCheckWorker::DetectionCheckWorker(CollisionTimeFinder * collision_time_finder, CollisionDetectionWorkCollector * work_collector, std::vector<int> * done)
	{
		done_ = done;
		collision_time_finder_ = collision_time_finder;
		work_collector_ = work_collector;
		kill_ = false;
	}

	DetectionCheckWorker::~DetectionCheckWorker()
	{

	}

	void DetectionCheckWorker::kill()
	{
		kill_ = true;
	}

	void DetectionCheckWorker::run()
	{
		while (!kill_)
		{
			CollisionPair col_pair;
			{
				// Lock on the collision worker.
				boost::mutex::scoped_lock sc_lock(*(work_collector_->getLock()));
				if (work_collector_->isEmpty())
				{
					// We are done, notify the simulation.
					done_->push_back(1);
					// Waiting for the next round.
					work_collector_->getCond()->wait(sc_lock);
					continue;
				}
				col_pair = work_collector_->getCollisionPair();
			}

			// Creating copies of objects.
			// It is also possible to create a lock on the two objects, but this is a bit faster.
			DynamicEntity * e1 = static_cast<DynamicEntity *> (col_pair.first->clone());
			Entity * e2 = col_pair.second->clone();

			// Not very pretty solution but the col contains the e1, e2 not the real ones.
			Collision * col = const_cast<Collision *> (collision_time_finder_->findCollisionTime(e1, e2, work_collector_->getTimeStep(), 100000));

			// Delete copies.
			delete e1;
			delete e2;

			if (col)
			{
				col->first = col_pair.first;
				col->second = col_pair.second;
			}
			// Enqueue the found collision.
			work_collector_->enqueueCollisionSynchronized(col);
		}
	}
}
